Shallow Size 和 Retained Size

在使用MAT工具分析JVM内存占用情况的时候,我们经常会遇到两个出现频率很高的名词 Shallow SizeRetained Size

这两个名词代表的是对象所占用的内存大小(JAVA对象大小=对象头+实例数据+对齐填充)。

下面是Mat文档里对Shallow Size 和 Retained Size的解释:

Shallow heap is the amount of memory consumed by one object. An Object requires 32 (or 64 bits, depending on the architecture) for each reference. Primitives such as integers and longs require 4 or 8 bytes, etc… While this can be interesting, the more useful metric is the Retained Heap.

The retained heap shows the sum of the shallow heap size of all objects that would be removed when this object is garbage collected. For example, if an ArrayList held 100,000 items, and each item required 16 bytes, then removing the ArrayList would free 16 x 100,000 + X, where X is the shallow size of the ArrayList. (Note: this assumes that these objects are only being referenced by the ArrayList, and not elsewhere).

The retained heap is computed by adding the size all the objects in the retained set. A retained set of X is the set of objects which would be removed by the GC when X is collected.

The retained heap can be calculated in two different ways, using the quick approximation or the precise retained size.

Shallow Size

非数组类型的对象的Shallow Size

shallow_size=对象头+各成员变量大小之和+对齐填充

这里的各成员变量大小之和就是实例数据,如果存在继承情况,当然要包含父类的成员变量。

注:记住不包含所引用的对象本身的大小。

数组类型对象的Shallow Size

shallow_size=对象头+类型变量大小*数组长度+对齐填充,其中如果类型是引用类型则是4字节或8字节(64位系统),如果是boolean类型则是1字节,以此类推。

注:这里的类型变量大小*数组长度就是实例数据,强调是变量不是对象本身。

image-20201124153513623

Retained Size

Retained Size 对象本身大小(即shallow heap大小)与其所引用对象大小之和。

换个说法就是当前对象被GC后,从Heap上总共能释放掉的内存,强调是GC后能释放的。即要排除被GC Roots直接或间接引用的对象。

当然这里面还会包括一些java语言特性的数据存储单元,就是说实际retained size会比我们计算出来的大一点。

image-20201124153525769

图中 GC Roots直接引用了A和B两个对象,对象A的Retained Size = 对象A的Shallow Size

B对象的Retained Size = B对象的Shallow Size + C对象的Shallow Size,需要注意的是,这里是不包括

D对象的,因为D对象还被GC Roots 引用了。如果D对象没有被GC Roots 引用,那么 B对象的Retained Size = B 对象的Shallow Size + C对象的Shallow Size + D对象的Shallow Size

image-20201124153536590

非数组对象的Retained Size

Retained Size=当前对象shallow_size+当前对象可直接或间接引用到的对象的shallow_size总和。(间接引用的含义:A->B->C, C就是间接引用)。

数组对象的Retained Size

数组的元素类型是引用类型

Retained Size=数组对象的shallow_size+数组中各个引用对象的shallow_size之和。

数组的元素类型为基本数据类型

Retained Size=数组对象的shallow_size+数组中各基本数据类型大小之和。

参考资料

  1. Shallow heap & Retained heap
  2. 10 Tips for using the Eclipse Memory Analyzer - EclipseSource
显示评论